package com.example.flutter.plugin.flutter_plugin

import android.os.Handler
import android.util.Log
import androidx.annotation.NonNull

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

/** FlutterPlugin */
class FlutterPlugin : FlutterPlugin, MethodCallHandler {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private lateinit var channel: MethodChannel
    val TAG_NAME: String = "From_Native"
    val eventChanelName: String = "com.ducafecat.counter/eventChannel"
    private var eventChannel: EventChannel.EventSink? = null
    private var count: Int = 0
    private var eventHandler: Handler? = null
    private lateinit var binaryMessenger: BinaryMessenger


    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_plugin")
        channel.setMethodCallHandler(this)
        binaryMessenger = flutterPluginBinding.binaryMessenger
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        if (call.method == "getPlatformVersion") {
            result.success("Android ${android.os.Build.VERSION.RELEASE}")
        } else if (call.method == "add") {
            val a = call.argument<Int>("a") as Int
            val b = call.argument<Int>("b") as Int
            val sum = add(a, b)
            result.success(sum)
        } else if (call.method == "startCounting") {
            EventChannel(binaryMessenger, eventChanelName).setStreamHandler(object :
                EventChannel.StreamHandler {
                override fun onListen(args: Any?, events: EventChannel.EventSink?) {
                    Log.w(TAG_NAME, "Add listener")
                    eventChannel = events
                    count = 0
                    eventHandler = Handler()
                    runnable.run()
                }

                override fun onCancel(args: Any?) {
                    Log.w(TAG_NAME, "Cancelling listener")
                    eventHandler?.removeCallbacks(runnable)
                    eventHandler = null
                    count = 0
                    eventChannel = null
                }

            })
            result.success(true)
        } else {
            result.notImplemented()
        }
    }

    private fun add(a: Int, b: Int): Int {
        return a + b
    }

    private val runnable = object : Runnable {
        override fun run() {
            val totalCount = 50
            if (count >= totalCount) {
                eventChannel?.endOfStream()
            } else {
                count++
                eventChannel?.success(count)
            }
            eventHandler?.postDelayed(this, 200)
        }
    }

    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
        eventHandler?.let {
            eventChannel?.endOfStream()
            it.removeCallbacks(runnable)
            eventHandler = null
            eventChannel = null
        }
    }
}
